package main

import (
	"context"
	clientv3 "go.etcd.io/etcd/client/v3"
	"google.golang.org/grpc"
	"log"
	"net"
	"os"
	"os/signal"
	"share-grpc/pb"
	"share-grpc/register"
	"share-grpc/user/database"
	"syscall"
)

// 定义类
type server struct{}

// Register 绑定类方法，实现接口
// 用户注册
func (s *server) Register(ctx context.Context, req *pb.RegisterRequest) (resp *pb.RegisterResponse, err error) {
	log.Println("调用微服务里面的注册方法")
	lastInsertID, err := database.SaveUserToDB(req.User.Username, req.User.Password, req.User.Email)

	resp = &pb.RegisterResponse{}
	resp.UserId = lastInsertID
	return
}

const etcdHost = "etcd:2379"

func main() {
	toInit()

	// 1. 初始化 grpc 对象
	s := grpc.NewServer()

	// 2. 注册服务
	pb.RegisterUserCenterServer(s, &server{})

	// 3. 创建监听器，指定 IP 跟 port
	listener, err := net.Listen("tcp", ":7001")
	if err != nil {
		log.Println("监听出错： ", err)
		return
	}
	log.Println("设置监听成功")

	// 4. 启动服务
	if err := s.Serve(listener); err != nil {
		log.Println("启动 gRPC 失败：", err)
		return
	}
}

func toInit() {
	database.Initialize()

	// 注册 etcd
	endpoints := []string{
		etcdHost,
	}

	//B2.实例化etcd服务
	client3, err := clientv3.New(
		clientv3.Config{
			Endpoints: endpoints,
			//你还可以设置更过的参数 如果开启了auth验证 也可以配置username和password
		},
	)
	if err != nil {
		log.Println("实例化etcd服务失败", err)
	} else {
		log.Println("实例化etcd服务成功")
	}

	// 注册rpc服务到etcd中心
	reg := register.NewRegister("vector_rpc_server", client3, "server:7001")
	reg.Reg()
	log.Println("etcd 注册成功")

	// 健康检查
	// 接收来自系统的信号
	ch := make(chan os.Signal, 1)
	// 将信号写到ch管道当中去
	signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGQUIT)
	go func() {
		s := <-ch
		log.Println("无法检测到服务", s)
		reg.UnReg()
	}()
}
